package com.zhenyi.jiahua.index.app;

import java.util.Date;
import java.util.List;

import org.joda.time.DateTime;

import com.cjw.model.DBMap;
import com.jfinal.aop.Before;
import com.jfinal.aop.Clear;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.Kv;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jiahua.common.model.JhArrange;
import com.jiahua.common.model.JhArrangeStudent;
import com.jiahua.common.model.JhCourse;
import com.jiahua.common.model.JhSchool;
import com.jiahua.common.model.JhStudent;
import com.jiahua.common.model.JhStudentCourse;
import com.utils.AESUtils;
import com.utils.AuthUtils;
import com.utils.DateUtils;
import com.utils.PathUtils;
import com.zhenyi.jiahua.index.JHController;
import com.zhenyi.jiahua.interceptor.app.AppAuthInterceptor;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.json.JSONUtil;

@Clear
@Before({ AppAuthInterceptor.class })
public class HomeController extends JHController {

	private final Integer CANCEL_TIME = PropKit.getInt("CANCEL_TIME", 3600);
	private final Integer JOIN_TIME = PropKit.getInt("JOIN_TIME", 3600);

	private JhStudent getStudent() {
		return JhStudent.dao.findById(Long.valueOf(AuthUtils.getTokenUid(this)));
		// JhStudent student = JhStudent.dao.findById(1);
		// return student;
	}

	/**
	 * 登录页面
	 */
	@Clear
	public void index() {
		// if (StrKit.notBlank(AuthUtils.getTokenUid(this))) {
		// redirect("");
		// }
		String state = getPara("state", "");
		if (StrKit.notBlank(state)) {
			setAttr("state", URLUtil.decode(state));
		} else {
			setAttr("state", "");
		}
		String key = RandomUtil.randomString(16);
		setAttr("key", key);
		setSessionAttr("key", key);
		render("/jh/app/index.html");
	}

	private Ret isStudentEnable(JhStudent student) {
		if (!student.getType().equals(JhStudent.TYPE_STUDENT)) {
			renderFailure("非正式学员暂无权限订课");
			return Ret.fail("msg", "非正式学员暂无权限订课");
		}
		if (YES.equals(student.getIsLeave())) {
			renderFailure("离校中，暂未开放订课权限");
			return Ret.fail("msg", "离校中，暂未开放订课权限");
		}
		// if (!JhStudent.STATUS_IN.equals(student.getStatus())) {
		// renderFailure("非在读学员暂无权限订课");
		// return Ret.fail("msg", "非在读学员暂无权限订课");
		// }
		if (YES.equals(student.getIsDisable())) {
			renderFailure("暂无权限订课");
			return Ret.fail("msg", "暂无权限订课");
		}
		if (YES.equals(student.getIsOff())) {
			Date now = new Date();
			if (now.getTime() >= student.getOffTimeStart().getTime()
					&& now.getTime() <= student.getOffTimeEnd().getTime()) {
				renderFailure("休学中");
				return Ret.fail("msg", "休学中,暂无权限订课");
			}
		}
		return Ret.ok();
	}

	@Clear
	public void login() {
		String account = getPara("account");
		if (StrKit.isBlank(account)) {
			renderFailure(500, "账号/密码错误.");
			return;
		}
		String password = getPara("password");
		try {
			String key = getSessionAttr("key");
			password = AESUtils.decrypt(key, password);
			if (password == null) {
				renderFailure(500, "解密失败,请刷新重试");
				return;
			}
		} catch (Exception e) {
			LogKit.warn(account + "登录失败", e);
			renderFailure();
			return;
		}
		DBMap maps = new DBMap();
		maps.put("mobile", account);
		maps.put("password", password);
		JhStudent user = JhStudent.dao.searchFirst(maps);
		if (user == null) {
			renderFailure(500, "账号/密码错误");
			return;
		}
		// LogKit.info(user.getName() + " 登录");
		user.setLoginTime(new Date());

		// JhStudent student = user;
		// if (!student.getType().equals(JhStudent.TYPE_STUDENT)) {
		// renderFailure("非正式学员暂无权限订课");
		// return;
		// }
		// if (YES.equals(student.getIsLeave())) {
		// renderFailure("离校中，暂未开放订课权限");
		// return;
		// }
		// if (!JhStudent.STATUS_IN.equals(student.getStatus())) {
		// renderFailure("非在读学员暂无权限订课");
		// return;
		// }
		//
		// if (YES.equals(user.getIsDisable())) {
		// renderFailure("暂无权限订课");
		// return;
		// }

		Ret ret = isStudentEnable(user);
		if (ret.isFail()) {
			String msg = ret.getStr("msg");
			renderFailure(msg);
			return;
		}

		user.update();
		String token = AuthUtils.login(String.valueOf(user.getId()), this);
		renderSuccess(token);
	}

	public void logout() {
		AuthUtils.logout(this);
		redirect("/jh/app");
	}

	/**
	 * 选课 1.不能重复选课
	 */
	@Override
	public void submit() {
		String path = PathUtils.getFile("jh", "temp", "excel", DateUtil.today(), "StudentSubmit.txt");
		FileWriter fileWriter = new FileWriter(path);
		Long arrangeId = getParaToLong("arrangeId");
		JhArrange arrange = JhArrange.dao.findById(arrangeId);
		String topic = arrange.getTopic();
		Long courseId = arrange.getCourseId();
		JhCourse course = JhCourse.dao.findById(courseId);
		JhStudent student = getStudent();
		Long studentId = student.getId();
		String studentName = student.getName();
		Long schoolId = course.getSchoolId();
		Integer isEnable = arrange.getIsEnable();
		Integer isStudentDisable = student.getIsDisable();
		// Integer isVIP = arrange.getIsVIP();
		Integer isFixed = course.getIsFixed();
		String template = "\n=====" + DateUtil.now() + " " + studentId + ":" + studentName + " " + arrangeId + ":"
				+ topic + " =====";
		if (YES.equals(arrange.getIsOnClass())) {
			renderMsg("很遗憾,已过上课时间");
			fileWriter.append(template + " 已过上课时间");
			return;
		}

		Ret ret = isStudentEnable(student);
		if (ret.isFail()) {
			String msg = ret.getStr("msg");
			renderFailure(msg);
			fileWriter.append(template + msg);
			return;
		}
		// if (!student.getType().equals(JhStudent.TYPE_STUDENT)) {
		// renderMsg("非正式学员暂无权限订课");
		// return;
		// }
		// if (YES.equals(student.getIsLeave())) {
		// renderMsg("离校中，暂未开放订课权限");
		// return;
		// }
		// // System.out.println(student.getName() + " - " + student.getId());
		// if (!JhStudent.STATUS_IN.equals(student.getStatus())) {
		// renderMsg("非在读学员暂无权限订课");
		// return;
		// }
		/**
		 * 上课后不允许报课
		 */
		Date startTime = arrange.getStartTime();
		Date now = new Date();
		Long bet = (startTime.getTime() - now.getTime()) / 1000;
		if (bet <= JOIN_TIME) {
			renderMsg("很遗憾,已过订课时间");
			fileWriter.append(template + "已过订课时间");
			return;
		}
		if (isFixed.equals(1)) {
			renderMsg("您暂无固定课程订课权限,请联系校方人员");
			fileWriter.append(template + "无固定课程订课权限");
			return;
		}
		/**
		 * 是否选满
		 */
		if (!arrange.getLimit().equals(0)) {
			if (arrange.getJoinCount() >= arrange.getLimit()) {
				renderMsg("该课程人数已满,请联系校方人员");
				fileWriter.append(template + "课程人数已满");
				return;
			}
		}
		/**
		 * 学生是否禁用
		 */
		if (isStudentDisable.equals(1)) {
			renderMsg("您的账号已禁用,请联系校方人员");
			fileWriter.append(template + "账号已禁用");
			return;
		}
		/**
		 * 课程是否禁用
		 */
		if (isEnable.equals(0)) {
			renderMsg("该课程暂不开放订课权限");
			fileWriter.append(template + "不开放订课权限");
			return;
		}
		/**
		 * 非vip不能选vip的课
		 */
		// if (isVIP.equals(1) && student.getIsVIP().equals(0)) {
		// renderMsg("很遗憾,您暂无此课程订课权限");
		// return;
		// }

		/**
		 * 没普通课合同的VIP不能上普通课
		 */
		// if (isVIP.equals(0) && student.getIsVIP().equals(1) &&
		// student.getCanJoinNormal().equals(0)) {
		// renderMsg("VIP不能选择普通课程哦");
		// return;
		// }
		/**
		 * 等级是否符合
		 */
		// String levels = course.getLevels();
		String CourseTags = course.getTags();
		String tag = student.getTag();
		if (!CourseTags.contains(tag)) {
			renderMsg("该课程等级与您目前适用等级不符");
			fileWriter.append(template + "课程等级与您目前适用等级不符");
			return;
		}
		// String levelStr = String.valueOf(levels.charAt(student.getLevel() -
		// 1));
		// if (levelStr.equals("0")) {
		// renderMsg("");
		// return;
		// }
		/**
		 * 核心课剩余数不足
		 */
		if (YES.equals(course.getIsCount())) {
			Integer count = student.getCoreCourseLeft();
			if (count == null) {
				renderMsg("很遗憾,您的剩余课时数量不足");
				fileWriter.append(template + "剩余课时数量不足");
				return;
			}
			if (student.getCoreCourseLeft() <= 0) {
				renderMsg("很遗憾,您的剩余课时数量不足");
				fileWriter.append(template + "剩余课时数量不足2");
				return;
			}
		}
		/**
		 * 是否允许所有校区选定该校区课程
		 */
		Integer isAllCanJoin = course.getIsAllCanJoin();
		if (!isAllCanJoin.equals(1)) {
			if (!student.getSchoolId().equals(schoolId)) {
				renderMsg("很遗憾,您暂无该校区的订课权限");
				fileWriter.append(template + "无该校区的订课权限");
				return;
			}
		}
		/**
		 * 是否重复选课
		 */
		if (PropKit.getBoolean("JH_MUTISELECTION", false)) {
			// SqlPara onClassPara =
			// Db.use("jiahua").getSqlPara("JFFindStudentOnClassCourse",
			// studentId,
			// courseId,
			// arrange.getTopic());
			JhStudentCourse studentCourse = JhStudentCourse.dao.findById(courseId, studentId, topic);
			if (studentCourse != null) {
				renderMsg("您已重复选课,请联系校方人员");
				fileWriter.append(template + "重复选课");
				return;
			}
		}

		Kv kv = Kv.create();
		kv.set("studentId", studentId);
		kv.set("startTime", arrange.getStartTime());
		kv.set("endTime", arrange.getEndTime());
		SqlPara sameArrangePara = Db.use("jiahua").getSqlPara("JHFindStudentSimeArrangeTime", kv);
		List<Record> items = Db.use("jiahua").find(sameArrangePara);
		if (items.size() > 0) {
			renderMsg("该时间段内已选课程");
			return;
		}
		/**
		 * 报课
		 */
		JhArrangeStudent arrangeStudent = JhArrangeStudent.dao.findById(arrangeId, studentId);
		if (arrangeStudent != null) {
			if (arrangeStudent.getStatus() == null) {
				arrangeStudent.setStatus(JhArrangeStudent.STATUS_JOIN);
			} else if (arrangeStudent.getStatus().equals(JhArrangeStudent.STATUS_JOIN)) {
				arrangeStudent.setStatus(JhArrangeStudent.STATUS_JOIN);
				LogKit.info("已订课");
			} else if (arrangeStudent.getStatus().equals(JhArrangeStudent.STATUS_CANCEL)) {
				arrangeStudent.setStatus(JhArrangeStudent.STATUS_JOIN);
				arrangeStudent.setCancelTime(null);
				// LogKit.info("从取消到订课");
			} else {
				LogKit.warn("报课状态异常");
				fileWriter.append(template + "报课状态异常");
				renderFailure();
				return;
			}
			arrangeStudent.setType(JhArrangeStudent.TYPE_STUDENT_SELECT);
			arrangeStudent.update();
			arrange.updateJoinCount();
		} else {
			arrangeStudent = new JhArrangeStudent();
			arrangeStudent.setArrangeId(arrangeId);
			arrangeStudent.setStudentId(studentId);
			arrangeStudent.setStatus(JhArrangeStudent.STATUS_JOIN);
			arrangeStudent.setType(JhArrangeStudent.TYPE_STUDENT_SELECT);
			boolean flag = arrangeStudent.save();
			if (flag) {
				arrange.updateJoinCount();
			}
		}
		// LogKit.info(student.getName() + "预定成功");
		renderSuccess();
	}

	/**
	 * 课程列表
	 */
	@Override
	public void list() {
		JhStudent student = getStudent();
		if (student == null) {
			logout();
			return;
		}
		String date = getPara("date", DateUtil.today());
		String next = DateUtils.dateFormat(new DateTime(date).plusDays(1).toDate(), DateUtils.YYYYMMDD);
		String previous = DateUtils.dateFormat(new DateTime(date).plusDays(-1).toDate(), DateUtils.YYYYMMDD);
		setAttr("next", next);
		setAttr("previous", previous);
		setAttr("date", date);
		setAttr("week", new DateTime(date).dayOfWeek().get());
		String startTime = date + " 00:00:00";
		String endTime = date + " 23:59:59";
		List<JhSchool> schools = JhSchool.dao.findAll();
		setAttr("schools", schools);
		setAttr("schoolNum", schools.size());
		setAttr("student", student);
		Kv kv = Kv.create();
		kv.set("startTime", startTime);
		kv.set("endTime", endTime);
		kv.set("isHide", 0);
		kv.set("studentId", student.getId());
		kv.set("tag", student.getTag());
		Long schoolId = getParaToLong("schoolId");
		if (schoolId != null) {
			kv.set("schoolId", schoolId);
			setAttr("schoolId", schoolId);
		}
		SqlPara sqlPara = Db.use("jiahua").getSqlPara("JHFindCourseList", kv);
		List<Record> records = Db.use("jiahua").find(sqlPara);
		for (Record item : records) {
			item.set("startTime", DateUtil.format(item.getDate("startTime"), "HH:mm"));
			item.set("endTime", DateUtil.format(item.getDate("endTime"), "HH:mm"));
			String tags = item.getStr("tags");
			if (StrKit.notBlank(tags)) {
				item.set("tags", tags.substring(0, tags.length() - 1));
			}
		}
		setAttr("list", JsonKit.toJson(records));
		render("/jh/app/courseList.html");
	}

	/**
	 * 取消订课(距离上课1小时内不能取消)
	 */
	public void cancel() {
		Long arrangeId = getParaToLong("arrangeId");
		JhArrange arrange = JhArrange.dao.findById(arrangeId);
		Date startTime = arrange.getStartTime();
		Date now = new Date();
		Long bet = (startTime.getTime() - now.getTime()) / 1000;
		if (bet <= CANCEL_TIME) {
			renderMsg("超过取消时间");
			return;
		}
		JhStudent student = getStudent();
		Long studentId = student.getId();
		JhArrangeStudent arrangeStudent = JhArrangeStudent.dao.findById(arrangeId, studentId);
		if (arrangeStudent == null) {
			LogKit.info("取消失败" + arrangeId + "," + studentId);
			renderFailure();
			return;
		}
		arrangeStudent.setStatus(JhArrangeStudent.STATUS_CANCEL);
		arrangeStudent.setCancelTime(new Date());
		arrangeStudent.update();
		arrange.updateJoinCount();
		renderSuccess();
		LogKit.info(student.getName() + "取消成功");
	}

	/**
	 * 我的订课,还没上的课
	 */
	public void mine() {
		Kv kv = Kv.by("studentId", getStudent().getId());
		kv.set("startTime", new Date());
		SqlPara sqlPara = Db.use("jiahua").getSqlPara("JHFindMyCourse", kv);
		List<Record> records = Db.use("jiahua").find(sqlPara);
		for (Record item : records) {
			item.set("startTime", DateUtil.format(item.getDate("startTime"), DateUtils.YYYYMMDD_HHMM));
			item.set("endTime", DateUtil.format(item.getDate("endTime"), "HH:mm"));
			String tags = item.getStr("tags");
			if (StrKit.notBlank(tags)) {
				item.set("tags", tags.substring(0, tags.length() - 1));
			}
		}
		setAttr("list", JSONUtil.toJsonStr(records));
		render("/jh/app/myCourse.html");
	}

	/**
	 * 订课历史,已经上过的课
	 */
	public void history() {
		int page = getPage();
		setAttr("page", page);
		SqlPara sqlPara = Db.use("jiahua").getSqlPara("JHFindMyCourseEnded", Kv.by("studentId", getStudent().getId()));
		List<Record> records = Db.use("jiahua").paginate(page, PAGE_SIZE, sqlPara).getList();
		for (Record item : records) {
			item.set("startTime", DateUtil.format(item.getDate("startTime"), DateUtils.YYYYMMDD_HHMM));
			item.set("endTime", DateUtil.format(item.getDate("endTime"), "HH:mm"));
			String tags = item.getStr("tags");
			if (StrKit.notBlank(tags)) {
				item.set("tags", tags.substring(0, tags.length() - 1));
			}
		}
		setAttr("list", JsonKit.toJson(records));
		render("/jh/app/myCourse.html");
	}

	public void profile() {
		JhStudent student = getStudent();
		renderSuccess(student);
	}

	public void contractInfo() {
		JhStudent student = getStudent();
		setInfoItem(student);
		render("/jh/app/contractInfo.html");
	}
}
